// 定义类型
interface RGB {
  r: number;
  g: number;
  b: number;
}

interface CMYK {
  c: number; // 青色百分比 (0-100)
  m: number; // 洋红百分比 (0-100)
  y: number; // 黄色百分比 (0-100)
  k: number; // 黑色百分比 (0-100)
}
/**
 * 表示 HSV 颜色模型（色相、饱和度、明度）
 */
interface HSV {
  /**
   * 色相（Hue）
   * 表示颜色的类型，如红、绿、蓝等。
   * 取值范围：[0, 360)，单位是角度：
   * - 0°     -> 红色
   * - 120°   -> 绿色
   * - 240°   -> 蓝色
   */
  h: number;

  /**
   * 饱和度（Saturation）
   * 表示颜色的纯度或强度。
   * 取值范围：[0, 100]，单位是百分比：
   * - 0%     -> 灰色（无彩色）
   * - 100%   -> 完全饱和的颜色
   */
  s: number;

  /**
   * 明度 / 亮度（Value / Brightness）
   * 表示颜色的亮度。
   * 取值范围：[0, 100]，单位是百分比：
   * - 0%     -> 黑色
   * - 100%   -> 最亮的颜色
   */
  v: number;
}

/**
 * 表示 HSL 颜色模型（色相、饱和度、亮度）
 */
interface HSL {
  /**
   * 色相（Hue）
   * 表示颜色的基本类型（红、绿、蓝等）。
   * 取值范围：[0, 360)，单位是角度：
   * - 0°     -> 红色
   * - 120°   -> 绿色
   * - 240°   -> 蓝色
   */
  h: number;

  /**
   * 饱和度（Saturation）
   * 表示颜色的纯度或强度。
   * 取值范围：[0, 100]，单位是百分比：
   * - 0%     -> 灰色（无彩色）
   * - 100%   -> 完全饱和的颜色
   */
  s: number;

  /**
   * 亮度（Lightness）
   * 表示颜色的明暗程度。
   * 取值范围：[0, 100]，单位是百分比：
   * - 0%     -> 黑色
   * - 50%    -> 正常亮度
   * - 100%   -> 白色
   */
  l: number;
}
/**
 * HEX 转 RGB
 */
export const hexToRgb = (hex: string): RGB => {
  let normalizedHex = hex.replace(/^#/, '');
  if (normalizedHex.length === 3) {
    normalizedHex = normalizedHex
      .split('')
      .map((c) => c + c)
      .join('');
  }
  const bigint = parseInt(normalizedHex, 16);
  return {
    r: (bigint >> 16) & 255,
    g: (bigint >> 8) & 255,
    b: bigint & 255,
  };
};
/**
 * RGB 转 CMYK
 */
export const rgbToCmyk = ({ r, g, b }: RGB): CMYK => {
  if (r === 0 && g === 0 && b === 0) {
    return { c: 0, m: 0, y: 0, k: 1 }; // Black
  }

  // Normalize RGB values to [0, 1]
  r = r / 255;
  g = g / 255;
  b = b / 255;

  const k = 1 - Math.max(r, g, b);
  const c = (1 - r - k) / (1 - k);
  const m = (1 - g - k) / (1 - k);
  const y = (1 - b - k) / (1 - k);

  return {
    c: parseFloat((c * 100).toFixed(0)),
    m: parseFloat((m * 100).toFixed(0)),
    y: parseFloat((y * 100).toFixed(0)),
    k: parseFloat((k * 100).toFixed(0)),
  };
};
/**
 * RGB 转 Hsv
 */
export const rgbToHsv = ({ r, g, b }: RGB): HSV => {
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const delta = max - min;

  let h = 0;
  if (delta !== 0) {
    switch (max) {
      case r:
        h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
        break;
      case g:
        h = ((b - r) / delta + 2) * 60;
        break;
      case b:
        h = ((r - g) / delta + 4) * 60;
        break;
    }
  }

  const s = max === 0 ? 0 : delta / max;
  const v = max;

  return {
    h: Math.round(h),
    s: parseFloat((s * 100).toFixed(0)),
    v: parseFloat((v * 100).toFixed(0)),
  };
};
/**
 * RGB 转 Hsl
 */
export const rgbToHsl = ({ r, g, b }: RGB): HSL => {
  r /= 255;
  g /= 255;
  b /= 255;

  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  const delta = max - min;

  let h = 0;
  const l = (max + min) / 2;

  if (delta === 0) {
    // 无色差，灰色
    return { h: 0, s: 0, l: parseFloat((l * 100).toFixed(2)) };
  }

  switch (max) {
    case r:
      h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
      break;
    case g:
      h = ((b - r) / delta + 2) * 60;
      break;
    case b:
      h = ((r - g) / delta + 4) * 60;
      break;
  }

  const s = delta / (1 - Math.abs(2 * l - 1));
  return {
    h: Math.round(h),
    s: parseFloat((s * 100).toFixed(0)),
    l: parseFloat((l * 100).toFixed(0)),
  };
};
/**
 * Hex 转 CMYK
 */
export const hexToCmyk = (hex: string): CMYK => {
  const rgb = hexToRgb(hex);
  return rgbToCmyk(rgb);
};
/**
 * Hex 转 HSV
 */
export const hexToHsv = (hex: string): HSV => {
  const rgb = hexToRgb(hex);
  return rgbToHsv(rgb);
};

/**
 * Hex 转 HSL
 */
export const hexToHsl = (hex: string): HSL => {
  const rgb = hexToRgb(hex);
  return rgbToHsl(rgb);
};
/**
 * CMYK 转 RGB
 * 将给定的 CMYK 颜色值转换为对应的 RGB 值。
 *
 * @param c - Cyan 青色 [0, 100]
 * @param m - Magenta 品红 [0, 100]
 * @param y - Yellow 黄色 [0, 100]
 * @param k - Key (Black) 黑色 [0, 100]
 * @returns 对应的 RGB 值对象 { r, g, b }
 */
export const cmykToRgb = ({ c, m, y, k }: CMYK): RGB => {
  // 确保所有输入在 [0, 100] 范围内，并转换为比例形式 [0, 1]
  const C = Math.max(0, Math.min(100, c)) / 100;
  const M = Math.max(0, Math.min(100, m)) / 100;
  const Y = Math.max(0, Math.min(100, y)) / 100;
  const K = Math.max(0, Math.min(100, k)) / 100;

  // 计算 RGB 分量
  const r = Math.round(255 * (1 - C) * (1 - K));
  const g = Math.round(255 * (1 - M) * (1 - K));
  const b = Math.round(255 * (1 - Y) * (1 - K));

  return {
    r,
    g,
    b,
  };
};
/**
 * CMYK 转 Hex
 */
export const cmykToHex = ({ c, m, y, k }: CMYK): string => {
  const rgb = cmykToRgb({ c, m, y, k });
  return rgbToHex(rgb);
};
/**
 * 将 RGB 颜色值转换为十六进制（HEX）格式
 *
 * @param r - 红色分量，范围 [0, 255]
 * @param g - 绿色分量，范围 [0, 255]
 * @param b - 蓝色分量，范围 [0, 255]
 * @returns 表示颜色的 HEX 字符串，如 "#FF5733"
 */
export const rgbToHex = ({ r, g, b }: RGB): string => {
  /**
   * 对颜色分量进行限制：
   * - 确保数值在 [0, 255] 范围内
   * - 对浮点数进行四舍五入取整
   */
  const clamp = (val: number) => Math.max(0, Math.min(255, Math.round(val)));

  /**
   * 将十进制颜色分量转换为两位十六进制字符串
   * - 如果结果是一位数（例如 `f`），自动补零（变成 `0f`）
   */
  const toHex = (component: number) => component.toString(16).padStart(2, '0');

  // 转换每个通道并拼接成完整的 HEX 颜色字符串
  return `#${toHex(clamp(r))}${toHex(clamp(g))}${toHex(clamp(b))}`.toUpperCase();
};

/**
 * 将 HSV 转换为 RGB。
 *
 * @param h - 色相值 [0, 360)
 * @param s - 饱和度 [0, 100]
 * @param v - 亮度 [0, 100]
 * @returns 对应的 RGB 值对象 { r, g, b }
 */
export const hsvToRgb = ({ h, s, v }: HSV): RGB => {
  // 将 H 转换为 [0, 1] 区间，S 和 V 也转换为 [0, 1] 区间
  let hPrime = h / 60;
  let sPercent = s / 100;
  let vPercent = v / 100;

  let c = vPercent * sPercent; // Chroma
  let x = c * (1 - Math.abs((hPrime % 2) - 1));
  let m = vPercent - c;

  let r1, g1, b1;

  if (hPrime >= 0 && hPrime < 1) {
    [r1, g1, b1] = [c, x, 0];
  } else if (hPrime < 2) {
    [r1, g1, b1] = [x, c, 0];
  } else if (hPrime < 3) {
    [r1, g1, b1] = [0, c, x];
  } else if (hPrime < 4) {
    [r1, g1, b1] = [0, x, c];
  } else if (hPrime < 5) {
    [r1, g1, b1] = [x, 0, c];
  } else {
    [r1, g1, b1] = [c, 0, x];
  }

  let r = Math.round((r1 + m) * 255);
  let g = Math.round((g1 + m) * 255);
  let b = Math.round((b1 + m) * 255);

  return {
    r,
    g,
    b,
  };
};

/**
 * 将 HSL 颜色值转换为 RGB 颜色值
 */
export const hslToRgb = ({ h, s, l }: HSL): RGB => {
  // 归一化输入
  const hue = h < 0 || h >= 360 ? ((h % 360) + 360) % 360 : h;
  const saturation = Math.max(0, Math.min(100, s)) / 100;
  const lightness = Math.max(0, Math.min(100, l)) / 100;

  const c = (1 - Math.abs(2 * lightness - 1)) * saturation; // Chroma
  const x = c * (1 - Math.abs(((hue / 60) % 2) - 1)); // 中间值
  const m = lightness - c / 2; // 明度偏移

  let r1 = 0,
    g1 = 0,
    b1 = 0;

  if (hue >= 0 && hue < 60) {
    [r1, g1, b1] = [c, x, 0];
  } else if (hue < 120) {
    [r1, g1, b1] = [x, c, 0];
  } else if (hue < 180) {
    [r1, g1, b1] = [0, c, x];
  } else if (hue < 240) {
    [r1, g1, b1] = [0, x, c];
  } else if (hue < 300) {
    [r1, g1, b1] = [x, 0, c];
  } else {
    [r1, g1, b1] = [c, 0, x];
  }

  const r = Math.round((r1 + m) * 255);
  const g = Math.round((g1 + m) * 255);
  const b = Math.round((b1 + m) * 255);

  return { r, g, b };
};
/**
 * 给 HEX 颜色添加透明度，返回 rgba 字符串
 */
export const hexAlpha = (hex: string = '#000000', alpha: number = 0.1): string => {
  const { r, g, b } = hexToRgb(hex);
  return `rgba(${r}, ${g}, ${b}, ${Math.max(0, Math.min(1, alpha))})`;
};

//根据背景颜色计算出最佳的字体颜色（黑色或白色）
export const getFontColor = (bgColor: string = '#000000'): string => {
  const hex = bgColor.replace('#', '');
  const r = parseInt(hex.substring(0, 2), 16);
  const g = parseInt(hex.substring(2, 4), 16);
  const b = parseInt(hex.substring(4, 6), 16);

  // 计算相对亮度
  const brightness = (r * 299 + g * 587 + b * 114) / 1000;

  // 根据亮度选择字体颜色
  return brightness > 150 ? '#000000' : '#FFFFFF';
};
